using System;
using System.Collections.Generic;
using System.Text;
using Sedodream.Sudoku.Exceptions;
using System.Text.RegularExpressions;

namespace Sedodream.Sudoku.Board
{
	public class BoardFactory
	{
		public static IBoard CreateBoard(IBoardData board)
		{
			if (board == null)
				throw new ArgumentNullException("board", "board cannot be null");

			return new SudokuBoard(board);
		}
		public static IBoard CreateBoard(string boardDataStr)
		{
			try
			{
				if (boardDataStr == null || boardDataStr.Trim().Length <= 0)
					throw new ArgumentNullException("boardData", "boardData cannot be null");

				string[] rowStrings = boardDataStr.Split('\n');
				if (rowStrings == null || rowStrings.Length <= 0)
				{
					string message = string.Format("Unable to read board from string");
					throw new BoardSizeException(message);
				}

				int rowNumber = 0;
				int boardSideLength = int.MinValue;
				int?[,] strValues = null;
				IBoardData boardData = null;
				int boardSize = int.MinValue;
				Regex whiteSpaceRegex = new Regex(@"\s");
				foreach (string str in rowStrings)
				{
					if (str == null || str.Replace(" ", "").Length <= 0)
						continue;
					//remove white space characters
					
					string strToUse = whiteSpaceRegex.Replace(str, "");
					if (strToUse == null || strToUse.Length <= 0)
						continue;
					if (boardSideLength==int.MinValue)
					{
						boardSideLength = strToUse.Length;
						boardSize = (int)Math.Sqrt((double)boardSideLength);
						//boardData = new BoardData(boardSideLength);
						strValues = new int?[boardSideLength, boardSideLength];
					}
					int colNumber = 0;
					foreach (char c in strToUse.ToCharArray())
					{
						int? value = int.Parse(c.ToString());
						if (value == 0)
							value = null;
						strValues[rowNumber, colNumber++] = value;
					}
					rowNumber++;
					//TODO: FINISH HERE
				}
				boardData = new BoardData(boardSize,strValues);
				IBoard board = new SudokuBoard(boardData);
				foreach (ICell cell in board.Cells)
				{
					cell.Update();
				}

				return board;
			}
			catch (Exception ex)
			{
				string message = string.Format("Unable to create board. Message: {0}", ex.Message);
				throw new BoardCreationException(message, ex);
			}
		}
	}

}
